package com.mo.tools.poi;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.mo.tools.date.LocalDateTimeUtils;
import org.apache.poi.ss.usermodel.DateUtil;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @description: A
 * @author: e-Xingfu.Yang
 * @date: 2022/2/28 17:48
 */
public class DateTimeConvert implements Converter<Object> {

    @Override
    public Object convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        Date date = null;
        if (cellData.getType().equals(CellDataTypeEnum.NUMBER)) {
            date = DateUtil.getJavaDate(cellData.getNumberValue().doubleValue());
        }

        Field field = contentProperty.getField();
        if (field.getType().equals(LocalDateTime.class)) {
            if (date != null) {
                return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
            } else if (contentProperty.getDateTimeFormatProperty() == null) {
                return LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue());
            } else {
                return LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue(), contentProperty.getDateTimeFormatProperty().getFormat());
            }

        } else if (field.getType().equals(LocalDate.class)) {
            if (date != null) {
                return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate();
            } else if (contentProperty.getDateTimeFormatProperty() == null) {
                return LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue()).toLocalDate();
            } else {
                return LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue(), contentProperty.getDateTimeFormatProperty().getFormat()).toLocalDate();
            }

        } else if (field.getType().equals(Date.class)) {
            if (date != null) {
                return date;
            } else if (contentProperty.getDateTimeFormatProperty() == null) {
                return LocalDateTimeUtils.toDate(cellData.getStringValue());
            } else {
                return LocalDateTimeUtils.toDate(cellData.getStringValue(), contentProperty.getDateTimeFormatProperty().getFormat());
            }
        }else if (field.getType().equals(String.class)) {
            if (date != null) {
                return LocalDateTimeUtils.toString(date);
            } else if (contentProperty.getDateTimeFormatProperty() == null) {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue());
                return LocalDateTimeUtils.toString((localDateTime));
            } else {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime(cellData.getStringValue());
                return LocalDateTimeUtils.toString(localDateTime, contentProperty.getDateTimeFormatProperty().getFormat());
            }

        }

        return Converter.super.convertToJavaData(cellData, contentProperty, globalConfiguration);
    }

    @Override
    public WriteCellData<?> convertToExcelData(Object value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        Field field = contentProperty.getField();
        if (field.getType().equals(LocalDateTime.class)) {
            if (contentProperty.getDateTimeFormatProperty() == null) {
                return new WriteCellData<>(LocalDateTimeUtils.toString((LocalDateTime) value, LocalDateTimeUtils.FormatType.DEFAULT_DATE_TIME));
            } else {
                return new WriteCellData<>(
                        LocalDateTimeUtils.toString((LocalDateTime) value, contentProperty.getDateTimeFormatProperty().getFormat()));
            }

        } else if (field.getType().equals(LocalDate.class)) {
            if (contentProperty.getDateTimeFormatProperty() == null) {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((LocalDate) value);
                return new WriteCellData<>(LocalDateTimeUtils.toString(localDateTime, LocalDateTimeUtils.FormatType.DEFAULT_DATE_TIME));
            } else {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((LocalDate) value);
                return new WriteCellData<>(
                        LocalDateTimeUtils.toString(localDateTime, contentProperty.getDateTimeFormatProperty().getFormat()));
            }

        } else if (field.getType().equals(Date.class)) {
            if (contentProperty.getDateTimeFormatProperty() == null) {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((Date) value);
                return new WriteCellData<>(LocalDateTimeUtils.toString(localDateTime, LocalDateTimeUtils.FormatType.DEFAULT_DATE_TIME));
            } else {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((LocalDate) value);
                return new WriteCellData<>(
                        LocalDateTimeUtils.toString(localDateTime, contentProperty.getDateTimeFormatProperty().getFormat()));
            }

        } else if (field.getType().equals(String.class)) {
            if (contentProperty.getDateTimeFormatProperty() == null) {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((String) value);
                return new WriteCellData<>(LocalDateTimeUtils.toString(localDateTime, LocalDateTimeUtils.FormatType.DEFAULT_DATE_TIME));
            } else {
                LocalDateTime localDateTime = LocalDateTimeUtils.toLocalDateTime((String) value);
                return new WriteCellData<>(
                        LocalDateTimeUtils.toString(localDateTime, contentProperty.getDateTimeFormatProperty().getFormat()));
            }
        }
        return Converter.super.convertToExcelData(value, contentProperty, globalConfiguration);
    }
}
